package org.jsola.hr.service.excel;

import lombok.extern.slf4j.Slf4j;
import org.jsola.common.BeanKit;
import org.jsola.common.StrKit;
import org.jsola.exception.ParamException;
import org.jsola.hr.common.RegUtils;
import org.jsola.hr.common.oneKeyPay.AliGetUserInfo;
import org.jsola.hr.constant.TransferAccountsPayStatusEnum;
import org.jsola.hr.constant.TransferAccountsTypeEnum;
import org.jsola.hr.dto.TransferAccountsDetailAddDTO;
import org.jsola.hr.dto.excel.TransferAccountsDetailImportDTO;
import org.jsola.hr.entity.EmpInfoDO;
import org.jsola.hr.entity.TransferAccountsDetailDO;
import org.jsola.hr.entity.TransferAccountsPeopleDO;
import org.jsola.hr.provider.IUserProviderService;
import org.jsola.hr.service.IEmpInfoService;
import org.jsola.hr.service.ITransferAccountInfoService;
import org.jsola.hr.service.ITransferAccountsDetailService;
import org.jsola.hr.service.ITransferAccountsPeopleService;
import org.jsola.hr.vo.payWx.VxWgkUserAuthResultVO;
import org.jsola.user.core.TokenUser;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author WU
 */
@Slf4j
public class TransferAccountsDetailListener extends BaseAnalysisEventListener<TransferAccountsDetailImportDTO> {

    /**
     * true忽略错误的行，false有错误中断上传
     */
    protected Boolean force = true;

    /**
     * 批次id
     */
    protected String batchId;

    /**
     * 公司id
     */
    protected String companyId;

    /**
     * token
     */
    protected TokenUser tokenUser;

    /**
     * 发放类型：1 支付宝 2 微信 3 银行
     */
    protected Integer type;



    /**
     * 导入失败的批次明细信息
     */
    protected List<TransferAccountsDetailAddDTO> failTransferAccountsDetailAddDTOList = new ArrayList<>();

    /**
     * 导入成功的批次明细信息
     */
    protected List<TransferAccountsDetailAddDTO> successTransferAccountsDetailAddDTOList = new ArrayList<>();

    public TransferAccountsDetailListener(String batchId, String companyId, TokenUser tokenUser, Integer type) {
        this.batchId = batchId;
        this.companyId = companyId;
        this.tokenUser = tokenUser;
        this.type = type;
    }


    /**
     * 转换数据(入库到人员库)
     */
    @Override
    public void saveData() {
        log.info("{}条数据，开始转换！", dataList.size());
        if (dataList.size() == 0) {
            log.warn("没有数据需要转换");
            throw new ParamException("导入的数据为空，请检查模板中是否有内容");
        }
        String failField;
        if (type.equals(TransferAccountsTypeEnum.ZFB.getValue())) {
            failField = "支付宝号";
        } else if (type.equals(TransferAccountsTypeEnum.VX.getValue())) {
            failField = "姓名";
        } else {
            failField = "银行卡号";
        }
        Map<String, String> idCardMap = new HashMap<>(8);
        Map<String, String> phoneMap = new HashMap<>(8);
        Map<String, String> identityMap = new HashMap<>(8);
        ITransferAccountsDetailService transferAccountsDetailService = BeanKit.getBean(ITransferAccountsDetailService.class);
        List<TransferAccountsDetailDO> transferAccountsDetailDOList = transferAccountsDetailService.selectByBatchId(batchId, tokenUser.getSiteId());
        List<String> existIdCards = transferAccountsDetailDOList.stream().map(TransferAccountsDetailDO::getIdCard)
                .collect(Collectors.toList());
        List<String> existPhones = transferAccountsDetailDOList.stream().map(TransferAccountsDetailDO::getPhone)
                .collect(Collectors.toList());
        List<String> existIdentitys = transferAccountsDetailDOList.stream().map(TransferAccountsDetailDO::getIdentity)
                .collect(Collectors.toList());
        IEmpInfoService empInfoService = BeanKit.getBean(IEmpInfoService.class);
        IUserProviderService userProviderService = BeanKit.getBean(IUserProviderService.class);
        ITransferAccountsPeopleService transferAccountsPeopleService = BeanKit.getBean(ITransferAccountsPeopleService.class);
        ITransferAccountInfoService transferAccountInfoService = BeanKit.getBean(ITransferAccountInfoService.class);
        int yetNumber = transferAccountsDetailDOList.size();
        for (int i = 0; i < dataList.size(); i++) {
            // 新建返回对象
            TransferAccountsDetailAddDTO transferAccountsDetailAddDTO = new TransferAccountsDetailAddDTO();
            // 设置值
            TransferAccountsDetailImportDTO transferAccountsDetailImportDTO = dataList.get(i);
            String name = transferAccountsDetailImportDTO.getName();
            String idCard = transferAccountsDetailImportDTO.getIdCard();
            String phone = transferAccountsDetailImportDTO.getPhone();
            BigDecimal money = null;
            String zfbIdentity = transferAccountsDetailImportDTO.getZfbIdentity();
            String bankIdentity = transferAccountsDetailImportDTO.getBankIdentity();
            String bankName = transferAccountsDetailImportDTO.getBankName();
            if (TransferAccountsTypeEnum.ZFB.getValue().equals(type)) {
                transferAccountsDetailAddDTO.setIdentity(zfbIdentity);
            } else if (TransferAccountsTypeEnum.BANK.getValue().equals(type)) {
                transferAccountsDetailAddDTO.setIdentity(bankIdentity);
            }
            transferAccountsDetailAddDTO.setName(name);
            transferAccountsDetailAddDTO.setIdCard(idCard);
            transferAccountsDetailAddDTO.setPhone(phone);
            if (StrKit.isEmpty(name)) {
                transferAccountsDetailAddDTO.setImportFailReason("姓名为空");
                transferAccountsDetailAddDTO.setFailField("姓名");
                failTransferAccountsDetailAddDTOList.add(transferAccountsDetailAddDTO);
                continue;
            }
            if (StrKit.isEmpty(idCard)) {
                transferAccountsDetailAddDTO.setImportFailReason("姓名或身份证号为空");
                transferAccountsDetailAddDTO.setFailField("身份证号");
                failTransferAccountsDetailAddDTOList.add(transferAccountsDetailAddDTO);
                continue;
            }
            if (TransferAccountsTypeEnum.ZFB.getValue().equals(type) && StrKit.isEmpty(zfbIdentity)) {
                transferAccountsDetailAddDTO.setImportFailReason("支付宝账号为空");
                transferAccountsDetailAddDTO.setFailField(failField);
                failTransferAccountsDetailAddDTOList.add(transferAccountsDetailAddDTO);
                continue;
            }
            if (TransferAccountsTypeEnum.BANK.getValue().equals(type)) {
                if (StrKit.isEmpty(bankIdentity)) {
                    transferAccountsDetailAddDTO.setImportFailReason("银行卡账号为空");
                    transferAccountsDetailAddDTO.setFailField(failField);
                    failTransferAccountsDetailAddDTOList.add(transferAccountsDetailAddDTO);
                    continue;
                }
            }
            if (StrKit.isNotEmpty(transferAccountsDetailImportDTO.getMoney())) {
                try {
                    money = new BigDecimal(transferAccountsDetailImportDTO.getMoney());
                    transferAccountsDetailAddDTO.setMoney(money);
                    // 金额不能小于1元
                    if (money.compareTo(new BigDecimal("1")) < 0) {
                        transferAccountsDetailAddDTO.setImportFailReason("发放金额不能小于1元");
                        transferAccountsDetailAddDTO.setFailField("发放金额");
                        failTransferAccountsDetailAddDTOList.add(transferAccountsDetailAddDTO);
                        continue;
                    }
                } catch (NumberFormatException e) {
                    transferAccountsDetailAddDTO.setImportFailReason("金额格式不正确！导入的金额为："
                            + transferAccountsDetailImportDTO.getMoney());
                    transferAccountsDetailAddDTO.setFailField("发放金额");
                    failTransferAccountsDetailAddDTOList.add(transferAccountsDetailAddDTO);
                    continue;
                }
            }
            // 校验手机号格式
            if (StrKit.isNotEmpty(phone)) {
                if (!RegUtils.isMobile(phone)) {
                    transferAccountsDetailAddDTO.setImportFailReason("手机号格式不对");
                    transferAccountsDetailAddDTO.setFailField("手机号");
                    failTransferAccountsDetailAddDTOList.add(transferAccountsDetailAddDTO);
                    continue;
                }
                if (phoneMap.containsKey(phone)) {
                    transferAccountsDetailAddDTO.setImportFailReason("手机号不能和前面的重复");
                    transferAccountsDetailAddDTO.setFailField("手机号");
                    failTransferAccountsDetailAddDTOList.add(transferAccountsDetailAddDTO);
                    continue;
                }
                if (existPhones.contains(phone)) {
                    transferAccountsDetailAddDTO.setImportFailReason("手机号在批次明细中已存在");
                    transferAccountsDetailAddDTO.setFailField("手机号");
                    failTransferAccountsDetailAddDTOList.add(transferAccountsDetailAddDTO);
                    continue;
                }
            }
            // 校验身份证号格式
            if (!RegUtils.isIdCard(idCard)) {
                transferAccountsDetailAddDTO.setImportFailReason("身份证号格式不对");
                transferAccountsDetailAddDTO.setFailField("身份证号");
                failTransferAccountsDetailAddDTOList.add(transferAccountsDetailAddDTO);
                continue;
            }
            // 身份证号重复校验
            if (idCardMap.containsKey(idCard)) {
                transferAccountsDetailAddDTO.setImportFailReason("身份证号不能和前面的重复");
                transferAccountsDetailAddDTO.setFailField("身份证号");
                failTransferAccountsDetailAddDTOList.add(transferAccountsDetailAddDTO);
                continue;
            }
            if (existIdCards.contains(idCard)) {
                transferAccountsDetailAddDTO.setImportFailReason("身份证信息在批次明细中已存在!");
                transferAccountsDetailAddDTO.setFailField("身份证号");
                failTransferAccountsDetailAddDTOList.add(transferAccountsDetailAddDTO);
                continue;
            }
            // 校验支付宝账号格式
            if (StrKit.isNotEmpty(zfbIdentity)) {
                if (!RegUtils.isMobile(zfbIdentity) && !RegUtils.isEmail(zfbIdentity)) {
                    transferAccountsDetailAddDTO.setImportFailReason("支付宝账号格式不对！（支付宝登录账号：邮箱或手机号）!");
                    transferAccountsDetailAddDTO.setFailField(failField);
                    failTransferAccountsDetailAddDTOList.add(transferAccountsDetailAddDTO);
                    continue;
                }
            }
            // 校验银行卡号
            if (StrKit.isNotEmpty(bankIdentity)) {
                if (!RegUtils.isBankCard(bankIdentity)) {
                    transferAccountsDetailAddDTO.setImportFailReason("银行卡号格式不对!");
                    transferAccountsDetailAddDTO.setFailField(failField);
                    failTransferAccountsDetailAddDTOList.add(transferAccountsDetailAddDTO);
                    continue;
                }
            }
            // 正确数据  判断是否需要新增人员库  返回明细
            TransferAccountsPeopleDO transferAccountsPeopleDO = transferAccountsPeopleService
                    .selectByIdCard(idCard, tokenUser.getSiteId());
            if (transferAccountsPeopleDO != null) {
                // 校验是否允许修改
                String error = transferAccountsPeopleService.checkUpdate(transferAccountsPeopleDO, name, phone,
                        zfbIdentity, bankIdentity, bankName);
                if (StrKit.isNotEmpty(error)) {
                    transferAccountsDetailAddDTO.setImportFailReason(error);
                    transferAccountsDetailAddDTO.setFailField(failField);
                    failTransferAccountsDetailAddDTOList.add(transferAccountsDetailAddDTO);
                    continue;
                }
                // 查询到了  修改为导入的信息
                transferAccountsDetailAddDTO.setIdentity(transferAccountsPeopleDO.getVxIdentity());
                if (type.equals(TransferAccountsTypeEnum.VX.getValue())) {
                    transferAccountsDetailAddDTO.setIdentityBinding(transferAccountsPeopleDO.getIsVxBinding());
                }
                setInfo(transferAccountsPeopleDO, transferAccountsDetailAddDTO, zfbIdentity, bankIdentity,
                        name, phone, idCard, bankName, null, userProviderService, transferAccountInfoService);
                transferAccountsPeopleService.updateDO(transferAccountsPeopleDO, tokenUser);
            } else {
                // 新增人员库信息
                transferAccountsPeopleDO = new TransferAccountsPeopleDO();
                setInfo(transferAccountsPeopleDO, transferAccountsDetailAddDTO, zfbIdentity, bankIdentity,
                        name, phone, idCard, bankName, empInfoService, userProviderService, transferAccountInfoService);
                transferAccountsPeopleDO = transferAccountsPeopleService.save(transferAccountsPeopleDO,
                        tokenUser.getSiteId(), tokenUser.getUserId());
            }
            if (StrKit.isNotEmpty(transferAccountsDetailAddDTO.getIdentity())
                    && existIdentitys.contains(transferAccountsDetailAddDTO.getIdentity())) {
                transferAccountsDetailAddDTO.setImportFailReason("转账账号在批次明细中已存在!");
                transferAccountsDetailAddDTO.setFailField(failField);
                failTransferAccountsDetailAddDTOList.add(transferAccountsDetailAddDTO);
                continue;
            }
            if (identityMap.containsKey(transferAccountsDetailAddDTO.getIdentity())) {
                transferAccountsDetailAddDTO.setImportFailReason("转账账号重复!");
                transferAccountsDetailAddDTO.setFailField(failField);
                failTransferAccountsDetailAddDTOList.add(transferAccountsDetailAddDTO);
                continue;
            }
            transferAccountsDetailAddDTO.setPeopleId(transferAccountsPeopleDO.getId());
            idCardMap.put(idCard, idCard);
            phoneMap.put(phone, phone);
            if (StrKit.isNotEmpty(transferAccountsDetailAddDTO.getIdentity())) {
                identityMap.put(transferAccountsDetailAddDTO.getIdentity(), transferAccountsDetailAddDTO.getIdentity());
            }
            yetNumber++;
            successTransferAccountsDetailAddDTOList.add(transferAccountsDetailAddDTO);
        }
        if (yetNumber > 500) {
            throw new ParamException("一个批次最多添加500人，请分批次进行！");
        }
        log.info("转换成功！");
    }

    private void setInfo(TransferAccountsPeopleDO transferAccountsPeopleDO,
                         TransferAccountsDetailAddDTO transferAccountsDetailAddDTO,
                         String zfbIdentity, String bankIdentity,
                         String name, String phone, String idCard, String bankName,
                         IEmpInfoService empInfoService,
                         IUserProviderService userProviderService,
                         ITransferAccountInfoService transferAccountInfoService) {
        transferAccountsPeopleDO.setCompanyId(companyId);
        transferAccountsPeopleDO.setName(name);
        transferAccountsPeopleDO.setPhone(phone);
        transferAccountsPeopleDO.setIdCard(idCard);
        transferAccountsPeopleDO.setOpeningBank(bankName);

        transferAccountsDetailAddDTO.setType(type);
        transferAccountsDetailAddDTO.setBatchId(batchId);
        transferAccountsDetailAddDTO.setPayStatus(TransferAccountsPayStatusEnum.NO_PAY.getValue());
        transferAccountsDetailAddDTO.setCompanyId(companyId);

        if (TransferAccountsTypeEnum.ZFB.getValue().equals(type)) {
            transferAccountsPeopleDO.setZfbIdentity(zfbIdentity);
            transferAccountsPeopleDO.setIsZfbBinding(true);
            transferAccountsDetailAddDTO.setIdentity(zfbIdentity);
        } else if (TransferAccountsTypeEnum.BANK.getValue().equals(type)) {
            transferAccountsPeopleDO.setBankIdentity(bankIdentity);
            transferAccountsPeopleDO.setIsBankBinding(true);
            transferAccountsDetailAddDTO.setIdentity(bankIdentity);
            if (StrKit.isEmpty(bankName)) {
                bankName = AliGetUserInfo.bankNameByBankNo(bankIdentity);
                bankName = AliGetUserInfo.bankNameToChinese(bankName);
                transferAccountsPeopleDO.setOpeningBank(bankName);
            }
            transferAccountsDetailAddDTO.setIsPingAnBank(bankName.contains("平安银行"));
            transferAccountsDetailAddDTO.setBankName(bankName);
        } else if (TransferAccountsTypeEnum.VX.getValue().equals(type) && empInfoService != null) {
            transferAccountsDetailAddDTO.setIdentityBinding(false);
            // 根据身份证号及公司ID查询花名册信息
            EmpInfoDO empInfoDO = empInfoService.selectEmpByIdCardAllStatus(idCard, companyId, tokenUser);
            if (empInfoDO == null || StrKit.isEmpty(empInfoDO.getUserId())) {
                return;
            }
            String openId = userProviderService.selectOpenIdByUserId(empInfoDO.getUserId(), tokenUser);
            boolean sisVxBinding = false;
            if (StrKit.isNotEmpty(openId)) {
                transferAccountsPeopleDO.setVxIdentity(openId);
                // 查询微工卡授权状态
                VxWgkUserAuthResultVO vxWgkUserAuthResultVO = transferAccountInfoService.selectUserAuthStatus(openId,
                        tokenUser.getSiteId());
                if (vxWgkUserAuthResultVO != null &&
                        "AUTHORIZED".equals(vxWgkUserAuthResultVO.getAuthorizeState())) {
                    sisVxBinding = true;
                }
                transferAccountsPeopleDO.setIsVxBinding(sisVxBinding);
                transferAccountsDetailAddDTO.setIdentity(openId);
            }
            transferAccountsDetailAddDTO.setIdentityBinding(sisVxBinding);
        }
    }


    public List<TransferAccountsDetailAddDTO> getFailTransferAccountsDetailAddDTOList() {
        return failTransferAccountsDetailAddDTOList;
    }

    public List<TransferAccountsDetailAddDTO> getSuccessTransferAccountsDetailAddDTOList() {
        return successTransferAccountsDetailAddDTOList;
    }

}
